package com.songlanyun.modules.order.service.impl;

import cn.hutool.core.map.MapUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.songlanyun.common.enums.OrderConstant;
import com.songlanyun.common.exception.RRException;
import com.songlanyun.common.utils.OrderGen;
import com.songlanyun.common.validator.ValidatorUtils;
import com.songlanyun.modules.exception.OrderException;
import com.songlanyun.modules.gains.service.ShopOrderGainsService;
import com.songlanyun.modules.order.entity.ChildOrder;
import com.songlanyun.modules.order.entity.Order;
import com.songlanyun.modules.order.entity.SaleServiceGoodsCard;
import com.songlanyun.modules.order.model.dto.CheckServiceGoodsDTO;
import com.songlanyun.modules.order.model.dto.RenewalServiceGoodsDTO;
import com.songlanyun.modules.order.service.ChildOrderService;
import com.songlanyun.modules.order.service.OrderService;
import com.songlanyun.modules.order.service.SaleServiceGoodsCardService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.Map;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.songlanyun.common.utils.PageUtils;
import com.songlanyun.common.utils.Query;

import com.songlanyun.modules.order.dao.SaleServiceGoodsVerificationRecordDao;
import com.songlanyun.modules.order.entity.SaleServiceGoodsVerificationRecord;
import com.songlanyun.modules.order.service.SaleServiceGoodsVerificationRecordService;


@Service("saleServiceGoodsVerificationRecordService")
public class SaleServiceGoodsVerificationRecordServiceImpl extends ServiceImpl<SaleServiceGoodsVerificationRecordDao, SaleServiceGoodsVerificationRecord> implements SaleServiceGoodsVerificationRecordService {


    @Autowired
    private SaleServiceGoodsCardService saleServiceGoodsCardService;

    @Autowired
    private ChildOrderService childOrderService;

    @Autowired
    private OrderService orderService;


    @Autowired
    private ShopOrderGainsService shopOrderGainsService;


    @Override
    public SaleServiceGoodsVerificationRecord create(SaleServiceGoodsVerificationRecord entity) {
        ValidatorUtils.validateEntity(entity);
        this.baseMapper.insert(entity);
        return entity;
    }

    @Override
    public SaleServiceGoodsVerificationRecord modify(SaleServiceGoodsVerificationRecord entity) {
        return null;
    }

    @Override
    public void remove(Long id) {

    }

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        Long orderId = MapUtil.getLong(params, "order_id");
        Long childOrderId = MapUtil.getLong(params, "child_order_id");

        IPage<SaleServiceGoodsVerificationRecord> page = this.page(
                new Query<SaleServiceGoodsVerificationRecord>().getPage(params),
                new LambdaQueryWrapper<SaleServiceGoodsVerificationRecord>()
                        .eq(SaleServiceGoodsVerificationRecord::getOrderId, orderId)
                        .eq(SaleServiceGoodsVerificationRecord::getChildOrderId, childOrderId)
                        .orderByDesc(SaleServiceGoodsVerificationRecord::getVerificationTime)
        );

        return new PageUtils(page);
    }

    @Override
    public List<SaleServiceGoodsVerificationRecord> loadByServiceGoodsCardId(Long serviceGoodsCardId) {
        List<SaleServiceGoodsVerificationRecord> list = this.list(new LambdaQueryWrapper<SaleServiceGoodsVerificationRecord>()
                .eq(SaleServiceGoodsVerificationRecord::getServiceGoodsCardId, serviceGoodsCardId));
        return list;
    }

    @Override
    public List<SaleServiceGoodsVerificationRecord> loadByOrderIdAndChildId(Long orderId, Long childOrderId) {
        List<SaleServiceGoodsVerificationRecord> list = this.list(
                new LambdaQueryWrapper<SaleServiceGoodsVerificationRecord>()
                        .eq(SaleServiceGoodsVerificationRecord::getOrderId, orderId)
                        .eq(SaleServiceGoodsVerificationRecord::getChildOrderId, childOrderId)
                        .orderByDesc(SaleServiceGoodsVerificationRecord::getVerificationTime)
        );
        return list;
    }

    @Override
    public ChildOrder check(String adminName, Long shopId, CheckServiceGoodsDTO dto) {
        SaleServiceGoodsCard saleServiceGoodsCard = saleServiceGoodsCardService.loadByCode(dto.getVerificationCode(), true);
        ChildOrder childOrder = childOrderService.loadByOrderAndChildId(saleServiceGoodsCard.getOrderId(), saleServiceGoodsCard.getChildOrderId(), true);

        //校验
        verifyServiceOrder(shopId, saleServiceGoodsCard, childOrder);

        /**
         * 创建核销记录
         */
        SaleServiceGoodsVerificationRecord record = new SaleServiceGoodsVerificationRecord();
        record.setChildOrderId(childOrder.getId());
        record.setOrderId(childOrder.getOrderId());
        record.setServiceGoodsCardId(saleServiceGoodsCard.getId());
        record.setVerificationCode(dto.getVerificationCode());
        record.setVerificationTime(new Date());
        record.setAdmin(adminName);
        record.setRemark(dto.getRemark());
        this.create(record);

        /**
         * 更新核销卡记录
         */

        saleServiceGoodsCard.setLastCheckTime(new Date());
        saleServiceGoodsCard.incUseCount();

        //最后一次核销不刷新核销码
        if (saleServiceGoodsCard.getResidueUseCount() > 0) {
            saleServiceGoodsCard.setVerificationCode(OrderGen.generateCheckNo());
        }

        if (saleServiceGoodsCard.getFirstCheckTime() == null) {
            saleServiceGoodsCard.setFirstCheckTime(new Date());
        }
        saleServiceGoodsCardService.modify(saleServiceGoodsCard);

        /**
         * 如果核销次数完成
         * 1、修改订单使用状态为已使用
         * 2、修改订单交易完成，封单
         * 3、结单
         **/
        if (saleServiceGoodsCard.getResidueUseCount() <= 0) {
            childOrder.setTransactionStatus(OrderConstant.TransactionStatus.COMPLETE);
            childOrder.setEnd(true);
            childOrder.setUseStatus(OrderConstant.UseStatus.ALL_USE);
            childOrder.setReceiptedNum(1);
            childOrder.setReceiptStatus(OrderConstant.ReceiptStatus.COMPLETE);
            childOrderService.modify(childOrder);

            Order order = orderService.getById(childOrder.getOrderId());
            order.setTransactionStatus(OrderConstant.TransactionStatus.COMPLETE);
            order.setEnd(true);
            order.setUseStatus(OrderConstant.UseStatus.ALL_USE);
            order.setReceiptStatus(OrderConstant.ReceiptStatus.COMPLETE);
            orderService.modify(order);

            //结算
            shopOrderGainsService.settlementServiceGoodsByChildOrder(childOrder);

        } else {
            /**
             * 如果核销次数没有完成
             * 1、修改订单使用状态为部分已使用
             */
            childOrder.setUseStatus(OrderConstant.UseStatus.PART_USE);
            childOrder.setTransactionStatus(OrderConstant.TransactionStatus.PART_RECEIPT);
            childOrderService.modify(childOrder);
            Order order = orderService.getById(childOrder.getOrderId());
            order.setUseStatus(OrderConstant.UseStatus.PART_USE);
            order.setTransactionStatus(OrderConstant.TransactionStatus.PART_RECEIPT);
            orderService.modify(order);
        }


        return childOrder;


    }

    @Override
    public void verifyServiceOrder(Long shopId, SaleServiceGoodsCard saleServiceGoodsCard, ChildOrder childOrder) {
        //服务订单不属于您的店铺
        if (!childOrder.getShopId().equals(shopId)) {
            throw new RRException(OrderException.SERVICE_CARD_SHOP_NOT_SAME);
        }
        //订单未支付
        if (!childOrder.getPaymentStatus().equals(OrderConstant.PaymentStatus.SUCCESS)) {
            throw new RRException(OrderException.ORDER_NOT_PAY);

        }
        //订单已存在维权
        if (!childOrder.getRightsStatus().equals(OrderConstant.RightsStatus.NO)) {
            throw new RRException(OrderException.RIGHTS_ORDER_EXISTS);

        }
        //服务订单已过期
        if (OrderConstant.ServiceGoodsUseStatus.EXPIRED.equals(saleServiceGoodsCard.getServiceGoodsUseStatus())) {
            throw new RRException(OrderException.SERVICE_CARD_USE_EXPIRED);
        }

        //服务订单已使用完成
        if (OrderConstant.ServiceGoodsUseStatus.COMPLETE.equals(saleServiceGoodsCard.getServiceGoodsUseStatus())) {
            throw new RRException(OrderException.SERVICE_CARD_USE_COMPLETE);
        }


    }

    /**
     * 续期
     *
     * @param shopId
     * @param dto
     */
    @Override
    public void renewal(Long shopId, RenewalServiceGoodsDTO dto) {
        ChildOrder childOrder = childOrderService.loadByOrderAndChildId(dto.getOrderId(), dto.getChildOrderId(), true);

        SaleServiceGoodsCard saleServiceGoodsCard = childOrder.loadServiceCard();
        if (saleServiceGoodsCard == null) {
            throw new RRException(OrderException.SERVICE_CARD_NOT_EXISTS);
        }

        //服务订单不属于您的店铺
        if (!childOrder.getShopId().equals(shopId)) {
            throw new RRException(OrderException.SERVICE_CARD_SHOP_NOT_SAME);
        }
        //订单未支付
        if (!childOrder.getPaymentStatus().equals(OrderConstant.PaymentStatus.SUCCESS)) {
            throw new RRException(OrderException.ORDER_NOT_PAY);

        }
        //订单已存在维权
        if (!childOrder.getRightsStatus().equals(OrderConstant.RightsStatus.NO)) {
            throw new RRException(OrderException.RIGHTS_ORDER_EXISTS);

        }

        //服务订单已使用完成
        if (OrderConstant.ServiceGoodsUseStatus.COMPLETE.equals(saleServiceGoodsCard.getServiceGoodsUseStatus())) {
            throw new RRException(OrderException.SERVICE_CARD_USE_COMPLETE);
        }

//        long tomorrowAndDayTimestamp = OrderConstant.getTomorrowAndDayTimestamp(System.currentTimeMillis(), dto.getRenewalNum());
        long tomorrowAndDayTimestamp = OrderConstant.getTomorrowAndDayTimestamp(saleServiceGoodsCard.getExpiredUseTime(), dto.getRenewalNum());

        saleServiceGoodsCard.setExpiredUseTime(tomorrowAndDayTimestamp);

        saleServiceGoodsCardService.modify(saleServiceGoodsCard);
    }
}